home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 31 / Amiga Format CD31 (1998-09-02)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1998-10].iso / -seriously_amiga- / hardware / transadf / source / util.c < prev    next >
C/C++ Source or Header  |  1998-07-20  |  7KB  |  283 lines

  1. /* util.c - Miscellaneous functions and macros
  2. ** Copyright (C) 1997,1998 Karl J. Ots
  3. ** 
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU General Public License as published by
  6. ** the Free Software Foundation; either version 2 of the License, or
  7. ** (at your option) any later version.
  8. ** 
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU General Public License for more details.
  13. ** 
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. */
  18.  
  19. /*------------------------------------*/
  20. /* Miscellaneous functions and macros */
  21. /*------------------------------------*/
  22.  
  23. #include <exec/types.h>
  24. #ifndef COMPILE_LITE
  25. #  include <dos/dos.h>
  26. #  include <clib/dos_protos.h>
  27.  
  28. #  include <time.h>
  29. #endif /* COMPILE_LITE */
  30.  
  31. #include <string.h>
  32. #include <ctype.h>
  33.  
  34. #include "util.h"
  35. #ifndef COMPILE_LITE
  36. #  include "gzip.h"
  37. #  include "pkzip.h"
  38. #endif /* COMPILE_LITE */
  39.  
  40.  
  41. /*
  42. ** Determine the unit number of a trackdisk device (DFx).
  43. ** Returns -1L if device name is not valid.
  44. ** devName should be of the format "DFx:\0", where x is a digit.
  45. */
  46. LONG Name2Unit (STRPTR devName)
  47. {
  48.   if ( (tolower(devName[0]) == 'd') && (tolower(devName[1]) == 'f') &&
  49.        (devName[2] >= '0') && (devName[2] <= '3') &&
  50.        (devName[3] == ':') && (devName[4] == '\0')
  51.      )
  52.     return devName[2] - '0';
  53.   
  54.   return (-1);
  55. }
  56.  
  57.  
  58. /* The following routines are only used in conjunction with de/compression */
  59. #ifndef COMPILE_LITE
  60.  
  61. /* 
  62. ** Return the file type, based on the 'magic number'
  63. ** ie the first few charcters.
  64. ** This function preserves current file position.
  65. */
  66. ULONG getFileType (BPTR file)
  67. {
  68.   UBYTE mag_num[4];
  69.   static UBYTE pkzip_mag[4] = {'P', 'K', 0x03, 0x04};
  70.   static UBYTE gzip_mag[2]  = {0x1F, 0x8B};
  71.   static UBYTE dos_mag[3]   = {'D',  'O',  'S'};
  72.   LONG oldp;
  73.   
  74.   oldp = Seek (file, 0, OFFSET_BEGINNING);
  75.   if ( Read (file, mag_num, 4) != 4) return FT_UNKNOWN;
  76.   Seek (file, oldp, OFFSET_BEGINNING);
  77.   
  78.   /* These are straight-forward comparisons */
  79.   if (!memcmp (mag_num, pkzip_mag, 4))
  80.     return FT_PKZIP;
  81.   if (!memcmp (mag_num, gzip_mag, 2))
  82.     return FT_GZIP;
  83.   if (!memcmp (mag_num, dos_mag, 3))
  84.     return FT_DOS;
  85.   
  86.   /* Zlib is a little tricky - The first char is usually 0x78, and the */
  87.   /* first two chars, when viewed together as an unsigned 16-bit int,  */
  88.   /* is a multiple of 31.                                              */
  89.   /* This probably needs a litte more work :)                          */
  90.   if ((mag_num[0] == 0x78) && !(((UWORD *)mag_num)[0] % 31))
  91.     return FT_ZLIB;
  92.   
  93.   /* If we get here, the type is unknown */
  94.   return FT_UNKNOWN;
  95. }
  96.  
  97.  
  98. /*
  99. ** Output a Header to the specified file depending on fileType.
  100. ** Return TRUE if no errors. else FALSE.
  101. */
  102. BOOL writeHead (BPTR outFile, STRPTR origName, ULONG fileType)
  103. {
  104.   /* Assume that the file is at the start */
  105.  
  106.   switch (fileType)
  107.   {
  108.   case FT_ZLIB:
  109.     /* No action necessary */
  110.     return TRUE;
  111.   
  112.   case FT_GZIP:
  113.     return writeGZHead (outFile, origName);
  114.   
  115.   case FT_PKZIP:
  116.     return writePKZHead (outFile, origName);
  117.   
  118.   case FT_PKZIP_ADD:
  119.     return writePKZHeadAdd (outFile, origName);
  120.   }
  121.   
  122.   /* Unknown type, error! */
  123.   return FALSE;
  124. }
  125.  
  126.  
  127. /*
  128. ** Finish writing a file depending on fileType.
  129. ** Return TRUE if no errors. else FALSE.
  130. */
  131. BOOL finishFile (BPTR outFile, ULONG CRC, ULONG CSize, ULONG USize, 
  132.                 ULONG fileType)
  133. {
  134.   switch (fileType)
  135.   {
  136.   case FT_ZLIB:
  137.     /* No action necessary */
  138.     return TRUE;
  139.   
  140.   case FT_GZIP:
  141.     return finishGZFile (outFile, CRC, USize);
  142.   
  143.   case FT_PKZIP:
  144.     return finishPKZFile (outFile, CRC, CSize, USize);
  145.     
  146.   case FT_PKZIP_ADD:
  147.     return finishPKZFileAdd (outFile, CRC, CSize, USize);
  148.   }
  149.   
  150.   /* Unknown type, error! */
  151.   return FALSE;
  152. }
  153.  
  154.  
  155. /*
  156. ** Skip the header of a specified file depending on file type.
  157. ** Return TRUE if no errors. else FALSE.
  158. */
  159. BOOL skipHead (BPTR inFile, STRPTR origName, ULONG fileType)
  160. {
  161.   /* Assume that the file is at the start */
  162.  
  163.   switch (fileType)
  164.   {
  165.   case FT_ZLIB:
  166.     /* No action necessary */
  167.     return TRUE;
  168.   
  169.   case FT_GZIP:
  170.     return skipGZHead (inFile);
  171.   
  172.   case FT_PKZIP:
  173.     return skipPKZHead (inFile, origName);
  174.   }
  175.   
  176.   /* Unknown type, error! */
  177.   return FALSE;
  178. }
  179.  
  180.  
  181. /*
  182. ** Read the a file depending on fileType and return the CRC
  183. ** and USize in supplied arrays.
  184. ** Return TRUE if no errors, else FALSE.
  185. */
  186. BOOL readTail (BPTR inFile, ULONG *CRC, ULONG *USize, ULONG fileType)
  187. {
  188.   switch (fileType)
  189.   {
  190.   case FT_ZLIB:
  191.     /* No action necessary */
  192.     return TRUE;
  193.   
  194.   case FT_GZIP:
  195.     return readGZTail (inFile, CRC, USize);
  196.   
  197.   case FT_PKZIP:
  198.     return readPKZTail (inFile, CRC, USize);
  199.   }
  200.   
  201.   /* Unknown type, error! */
  202.   return FALSE;
  203. }
  204.  
  205.  
  206. /*
  207. ** Return the current date and time in UNIX format.
  208. ** (ie No. seconds after 1-Jan-1970).
  209. */
  210. ULONG unixDate (void)
  211. {
  212.   struct DateStamp ds;
  213.   
  214.   DateStamp (&ds);
  215.   
  216.   /* Need to add 2922 Days (1970->1978) */
  217.   
  218.   return ((ds.ds_Tick / TICKS_PER_SECOND) + 
  219.           (ds.ds_Minute * 60) +
  220.           ((ds.ds_Days + 2922) * 86400));
  221. }
  222.  
  223.  
  224. /*
  225. ** Return the current date and time in DOS format.
  226. */
  227. ULONG  dosDate (void)
  228. {
  229.   /* The DOS date format is as follows:
  230.    * 7 bits: Year after 1980 (0 - 127).
  231.    * 4 bits: Month (1 - 12).
  232.    * 5 bits: Day (1 - 31).
  233.    * (16 bits)
  234.    * 
  235.    * 5 bits: Hour (0 - 23).
  236.    * 6 bits: Minute (0 - 59).
  237.    * 5 bits: Seconds / 2 (0 - 29).
  238.    * (16 bits)
  239.    * 
  240.    * Total = 32 bits = 1 long word.
  241.    */
  242.   
  243.   time_t t;
  244.   struct tm *tp;
  245.   
  246.   /* Get the time */
  247.   t = time (NULL); tp = localtime (&t);
  248.   
  249.   /* Adjust year to within DOS range */
  250.   if (tp->tm_year < 80) return 0x00210000;   /* 1-1-1980, 00:00:00 */
  251.   
  252.   return (((tp->tm_year - 80) << 25) | ((tp->tm_mon+1) << 21) | 
  253.           (tp->tm_mday << 16) | (tp->tm_hour << 11) | (tp->tm_min << 5) |
  254.           (tp->tm_sec >> 1));
  255. }
  256.  
  257.  
  258. /*
  259. ** Return little-endian format of supplied short.
  260. ** Can also be used to convert a short from little-endian.
  261. */
  262. UWORD LES (UWORD num)
  263. {
  264.   return (((num & 0xFF00) >> 8) |
  265.           ((num & 0x00FF) << 8));
  266. }
  267.  
  268.  
  269. /*
  270. ** Return little-endian format of supplied long.
  271. ** Can also be used to convert a long from little-endian.
  272. */
  273. ULONG LEL (ULONG num)
  274. {
  275.   return (((num & 0xFF000000) >> 24) |
  276.           ((num & 0x00FF0000) >> 8)  |
  277.           ((num & 0x0000FF00) << 8)  |
  278.           ((num & 0x000000FF) << 24));
  279. }
  280.  
  281.  
  282. #endif /* COMPILE_LITE */
  283.